package member.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import member.domain.Member;
import member.domain.MemberReceiveAddress;
import member.mapper.MemberReceiveAddressMapper;
import member.service.MemberService;
import member.mapper.MemberMapper;
import member.vo.*;
import org.apache.commons.lang.RandomStringUtils;
import com.feign.constant.AuthServerConstant;
import com.feign.utils.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author panghu
 * @description 针对表【ums_member(会员)】的数据库操作Service实现
 * @createDate 2023-03-04 21:04:05
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member>
        implements MemberService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private MemberReceiveAddressMapper memberReceiveAddressMapper;

    @Override
    public Member login(MemberUserLoginVo vo) {
        String phone = vo.getLoginacct();
        String password = vo.getPassword();

        //1、去数据库查询 SELECT * FROM ums_member WHERE username = ? OR mobile = ?
        Member Member = this.baseMapper.selectOne(new QueryWrapper<Member>()
                .eq("username", phone).or().eq("mobile", phone));
        if (ObjectUtils.isEmpty(Member)) {
            //登录失败
            return null;
        } else {
            //获取到数据库里的password
            String password1 = Member.getPassword();
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            //进行密码匹配
            boolean matches = passwordEncoder.matches(password, password1);
            if (matches) {
                //登录成功
                return Member;
            }
        }
        return null;
    }

    @Override
    public LoginResVo loginTemp(LoginVo vo, HttpServletRequest request) {
        String phone = vo.getPhone();
        String password = vo.getPassword();
        String userTempId = request.getHeader("userTempId");
        //1、去数据库查询 SELECT * FROM ums_member WHERE username = ? OR mobile = ?
        Member member = this.baseMapper.selectOne(new LambdaQueryWrapper<Member>()
                .eq(Member::getUsername, phone).or().eq(Member::getNickname, phone).eq(Member::getPassword, password));
        if (ObjectUtils.isEmpty(member)) {
            //登录失败
            return null;
        } else {
            // 登录成功
            LoginResVo loginResVo = new LoginResVo();
            loginResVo.setName(member.getUsername());
            loginResVo.setUserId(member.getId());
            loginResVo.setNickName(member.getNickname());
            String token = RandomStringUtils.randomAlphanumeric(30);
            loginResVo.setToken(token);
            String loginJsonResVoStr = JSON.toJSONString(loginResVo);
            // 将token作为key，user作为值存入redis中
            redisTemplate.opsForValue().set(AuthServerConstant.TOKEN + token, loginJsonResVoStr);
            return loginResVo;
        }
    }

    @Override
    public R register(RegisterVo registerVo) {
        // 校验手机号和验证码是否相对应
        String code = registerVo.getCode();
        // redis中的验证码
        String redisCode = redisTemplate.opsForValue().get(AuthServerConstant.CODE + registerVo.getPhone());
        if (!code.equals(redisCode)) {
            return R.error("验证码错误");
        }
        Member member = new Member();
        member.setNickname(registerVo.getPhone());
        member.setPassword(registerVo.getPassword());
        member.setUsername(registerVo.getPhone());
        this.baseMapper.insert(member);
        return R.ok("注册成功");
    }

    @Override
    public UserInfoVo getUserInfo(HttpServletRequest request) {
        // 获取请求头中的token
        String token = request.getHeader("token");
        //String userTempId = request.getHeader("userTempId");
        // 验证身份
        String user = redisTemplate.opsForValue().get(AuthServerConstant.TOKEN + token);
        if (ObjectUtils.isEmpty(user)) {
            return null;
        }
        //redisTemplate.opsForValue().get(AuthServerConstant.LOGIN_USER)
        LoginResVo loginResVo = JSONUtil.toBean(user, LoginResVo.class);
        UserInfoVo userInfoVo = new UserInfoVo();
        // 身份验证通过，返回该用户信息
        Member member = this.baseMapper.selectById(loginResVo.getUserId());
        userInfoVo.setId(member.getId());
        userInfoVo.setLoginName(member.getUsername());
        userInfoVo.setNickName(member.getNickname());
        userInfoVo.setName(member.getUsername());
        userInfoVo.setPasswd(member.getPassword());
        userInfoVo.setPhoneNum(member.getMobile());
        userInfoVo.setHeader(member.getHeader());
        return userInfoVo;
    }

    @Override
    public void logout(HttpServletRequest request) {
        // 退出登录，删除redis中的token
        String token = request.getHeader("token");
        if (ObjectUtils.isEmpty(token)) {
            return;
        }
        redisTemplate.delete(AuthServerConstant.TOKEN + token);
    }

    @Override
    public List<UserAddressVo> findUserAddressList(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (!ObjectUtils.isEmpty(token)) {
            // 获取当前登录用户的id
            String userStr = redisTemplate.opsForValue().get(AuthServerConstant.TOKEN + token);
            // 转换
            LoginResVo loginResVo = JSONUtil.toBean(userStr, LoginResVo.class);
            List<MemberReceiveAddress> memberReceiveAddressList = memberReceiveAddressMapper.selectList(new LambdaQueryWrapper<MemberReceiveAddress>().eq(MemberReceiveAddress::getMemberId, loginResVo.getUserId()));
            return memberReceiveAddressList.stream().map(item -> {
                UserAddressVo userAddressVo = new UserAddressVo();
                userAddressVo.setConsignee(item.getName());
                userAddressVo.setFullAddress(item.getDetailAddress());
                userAddressVo.setId(item.getId());
                userAddressVo.setIsDefault(item.getDefaultStatus());
                userAddressVo.setPhoneNum(item.getPhone());
                //userAddressVo.setProvinceId(item.getProvince());
                //userAddressVo.setRegionId(item.getRegion());
                userAddressVo.setUserId(item.getMemberId());
                return userAddressVo;
            }).collect(Collectors.toList());

        }
        return null;
    }


    @Override
    public MemberInfoVo getMemberInfoById(HttpServletRequest request) {
        // 获取当前登录人的信息
        String token = request.getHeader("token");
        if (!ObjectUtils.isEmpty(token)) {
            // 获取当前登录用户的id
            String userStr = redisTemplate.opsForValue().get(AuthServerConstant.TOKEN + token);
            // 转换
            LoginResVo loginResVo = JSONUtil.toBean(userStr, LoginResVo.class);
            // 查出用户
            Member member = this.getById(loginResVo.getUserId());
            MemberInfoVo memberInfoVo = new MemberInfoVo();
            // 属性对拷贝
            BeanUtils.copyProperties(member, memberInfoVo);
            if (member.getGender() == 1) {
                memberInfoVo.setGender("男");
            } else {
                memberInfoVo.setGender("女");
            }
            // 设置收获地址
            List<MemberReceiveAddress> memberReceiveAddressList = memberReceiveAddressMapper.selectList(new LambdaQueryWrapper<MemberReceiveAddress>().eq(MemberReceiveAddress::getMemberId, member.getId()));
            if (!ObjectUtils.isEmpty(memberReceiveAddressList)) {
                memberInfoVo.setMemberReceiveAddressList(memberReceiveAddressList);
            }
            return memberInfoVo;

        }
        return null;
    }

    @Override
    public void updateMember(MemberInfoVo memberInfoVo) {
        Member member = new Member();
        // 属性对拷
        BeanUtils.copyProperties(memberInfoVo, member);
        // 性别
        if (memberInfoVo.getGender().equals("男")) {
            member.setGender(1);
        } else {
            member.setGender(0);
        }
        // 更新
        this.update(member, new LambdaQueryWrapper<Member>().eq(Member::getId, member.getId()));
    }
}




